package cn.initcap.algorithm.graph;

import java.util.List;

/**
 * @author initcap
 * @date Created in 7/30/19 7:15 PM.
 */
public interface Graph<T, W extends Number & Comparable> {

    /**
     * 返回节点个数
     *
     * @return 节点数
     */
    int nodeSize();

    /**
     * 返回边的个数
     *
     * @return 边数
     */
    int marginSize();

    /**
     * 验证图中是否有从v到w的边
     *
     * @param v 开始节点
     * @param w 目标节点
     * @return true为有边
     */
    boolean hasEdge(int v, int w);

    /**
     * 向图中添加一个边, 权值为weight
     *
     * @param e 添加边
     */
    void addEdge(Edge<W> e);

    /**
     * 显示图的信息
     */
    void show();

    /**
     * 返回图中一个顶点的所有邻边
     * 由于java使用引用机制，返回不会带来额外开销,
     *
     * @param v 定点
     * @return 迭代器
     */
    Iterable<T> adj(int v);

    /**
     * 获取无向图指定节点读书
     *
     * @param v
     * @return
     */
    default int degree(int v) {
        if (isDirected()) {
            throw new IllegalArgumentException("directed graph no degree!");
        }
        return ((List) adj(v)).size();
    }

    /**
     * 获取指定节点入度数量
     *
     * @param v 节点
     * @return
     */
    int indegree(int v);

    /**
     * 获取指定节点出度数量
     *
     * @param v 节点
     * @return
     */
    int outdegree(int v);

    /**
     * 是否为有向图
     *
     * @return
     */
    boolean isDirected();

    /**
     * 数据校验
     *
     * @param node       需要验证的节点
     * @param sourceNode this.node
     */
    default void validateVertex(int node, int sourceNode) {
        if (node < 0 && node >= sourceNode) {
            throw new IllegalArgumentException("Invaild node : " + node);
        }
    }

}
